﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using com.hebg3.app.model;
using com.hebg3.util;
using com.hebg3.app.zip;
using System.IO;
using com.hebg3.cmd;
using com.hebg3.app.reg;

namespace com.hebg3.app {

  class AppManager {
    private InstallReg installReg = new InstallReg();

    #region 从xml文件中得到应用集合方法
    /// <summary>从xml文件中得到应用集合方法
    /// </summary>
    /// <param name="xmlPath"></param>
    /// <returns></returns>
    public List<App> getAppsByXml(String xmlPath) {
      try {
        List<App> list = new List<App>();
        //实例化doc对象
        XmlDocument doc = new XmlDocument();
        //加载xml
        doc.Load(xmlPath);
        //install节点
        XmlNode installNode = doc.SelectSingleNode("install");
        //install属性节点
        XmlNode installPropertiesNode = installNode.FirstChild;
        //apps节点
        XmlNode appsNode = installNode.LastChild;
        //遍历各个app节点,逐个构建App实例
        foreach( XmlNode appNode in appsNode.ChildNodes ) {

          App app = new App();

          app.setId(appNode.Attributes["id"].Value);//id
          app.setName(appNode.Attributes["name"].Value);//name
          app.setDescn(appNode.Attributes["descn"].Value);//descn
          app.setAppFileName(appNode.Attributes["appFileName"].Value);//appFile
          app.setVersion(appNode.Attributes["version"].Value);//version

          list.Add(app);
        }

        return list;

      } catch( Exception e ) {
        throw new ApplicationException(e.Message, e);
      }
    }
    #endregion

    #region 生成apps.xml方法
    public void genAppsXml(List<App> list, String xmlPath) {
      try {
        //实例化xml文档实例
        XmlDocument doc = new XmlDocument();
        //设置声明属性
        XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
        //创建根节点--安装节点
        XmlElement installNode = doc.CreateElement("install");
        //创建安装属性节点
        XmlElement installPropertiesNode = doc.CreateElement("install_properties");

        installPropertiesNode.SetAttribute("id", "" + 1);//id
        installPropertiesNode.SetAttribute("version", "1");//版本
        installPropertiesNode.SetAttribute("publishTime", new DateTime().ToString());//时间

        //添加安装属性节点到根节点
        installNode.AppendChild(installPropertiesNode);

        //apps节点
        XmlElement appsNode = doc.CreateElement("apps");
        #region 遍历所有应用,写xml文件
        foreach( App app in list ) {
          //应用节点
          XmlElement appNode = doc.CreateElement("app");
          //id
          appNode.SetAttribute("id", app.getId());
          //名称
          appNode.SetAttribute("name", app.getName());
          //descn
          appNode.SetAttribute("descn", app.getDescn());
          //version
          appNode.SetAttribute("version", app.getVersion());
          //将app节点放入Apps节点
          appsNode.AppendChild(appNode);
        }

        installNode.AppendChild(appsNode);

        doc.AppendChild(dec);//描述
        doc.AppendChild(installNode);//安装节点,根节点

        //xml设置
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;
        settings.Encoding = UnicodeEncoding.UTF8;

        XmlWriter writer = XmlWriter.Create(xmlPath, settings);
        doc.WriteTo(writer);

        writer.Flush();

        writer.Close();
      } catch( Exception e ) {
        Console.Out.WriteLine(e.Message);
      }


        #endregion

    }
    #endregion

    #region 拷贝zip包到用户目录本程序文件夹下方法
    /// <summary>拷贝zip包到用户目录本程序文件夹下方法
    /// </summary>
    /// <param name="zipFileName"></param>
    private void copyZip(String zipFileName) {
      //如果要拷贝的文件不存在,则抛出异常
      if( !File.Exists(zipFileName) ) {
        throw new ApplicationException("文件不存在");
      }
      String userAppDir = SysUtils.getUserAppDir();
      //如果用户目录下程序文件夹不存在,则建立
      if( !Directory.Exists(userAppDir) ) {
        try {
          //创建文件夹
          Directory.CreateDirectory(userAppDir);
        } catch( Exception e ) {
          throw new ApplicationException(e.Message, e);
        }
      }

      //否则拷贝zip文件到用户目录本程序文件夹下
      try {
        File.Copy(zipFileName, SysUtils.getUserAppZipFilePath(), true);
      } catch( Exception e ) {
        throw new ApplicationException(e.Message, e);
      }


    }
    #endregion

    #region 导入程序包方法
    /// <summary>导入程序包方法
    /// </summary>
    /// <param name="zipFileName"></param>
    public List<App> importApp(String zipFileName) {
      //拷贝zip包到用户目录本程序文件夹下
      copyZip(zipFileName);
      try {
        //解压zip文件到用户目录下本程序目录下的app文件夹
        UnZiper.unZip(SysUtils.getUserAppZipFilePath(), SysUtils.getUserAppAppsDir(), AppKeyConstants.ZIP_PWD);
        //分析xml文件,得到app集合
        //List<App> list = getAppsByXml(SysUtils.getUserAppAppsXmlPath());

        return listApps();

      } catch( Exception e ) {
        //遇到异常向外抛出异常
        throw new ApplicationException(e.Message, e);
      }
    }
    /// <summary>
    /// 分析xml文件,得到app集合
    /// </summary>
    /// <returns></returns>
    public List<App> listApps() {
      //分析xml文件,得到app集合
      List<App> list = getAppsByXml(SysUtils.getUserAppAppsXmlPath());

      return list;
    }
    #endregion

    #region 安装应用方法
    /// <summary>安装应用方法/// </summary>
    public void installApps(String userName,String userNumber) {
      //得到应用/游戏列表     
      List<App> apps = getAppsByXml(SysUtils.getUserAppAppsXmlPath());
      //迭代所有应用,逐个安装
      foreach( App app in apps ) {
        installApp(app, userName, userNumber);
      }
    }

    #endregion

    #region 安装一个应用方法
    /// <summary>安装一个应用方法
    /// </summary>
    /// <param name="app"></param>
    public String installApp(App app,String userName,String userNumber) {
      String commendString = AppKeyConstants.INSTALL_COMMAND + SysUtils.getUserAppAppsDir() + "\\" + app.getAppFileName();
      commendString = AppKeyConstants.INSTALL_COMMAND + SysUtils.getUserAppAppsDir() + commendString;
      Console.WriteLine("安装命令:-->"+commendString);

      //调用CommandDo的execute方法执行安装
      //String result = CommandDo.execute(commendString, 0);
      //改变当前路径命令
      String changeDirCmd = "cd " + SysUtils.getUserAppAppsDir();
      changeDirCmd = changeDirCmd.Replace("\\","/");
      String installCmd = AppKeyConstants.INSTALL_COMMAND + app.getAppFileName();
      List<String> commands = new List<String>();
      commands.Add(changeDirCmd);
      commands.Add("c:");
      commands.Add(installCmd);
      String result = CommandDo.execute(commands,0);
      //判断是否正确安装
      if(result != null && result.ToUpper().IndexOf("SUCCESS") !=-1){
        //记录安装
        installReg.regInstall(app, userName, userNumber);
      }
     
      //返回控制台得到的安装相应
      return result;
    }
    #endregion

    #region 添加一个应用
    /// <summary>添加一个应用
    /// </summary>
    /// <param name="app"></param>
    public void addApp(App app , String appFilePath) {
      String xmlPath = AppKeyConstants.APP_EXP_APPS_DIR_NAME + "/" + AppKeyConstants.APP_XML_FILE_NAME; 
      //在用户目录中的apps.xml如果存在,则添加记录,如果不存在,则创建
      //实例化doc对象
      XmlDocument doc = new XmlDocument();
      //如果xml不存在,则先创建
      if( !File.Exists(xmlPath) ) {
        //创建xml
        createXml(doc);
      } else {
        //加载xml
        doc.Load(xmlPath);
      }



    }
    #endregion
    #region 创建xml
    /// <summary>
    /// 创建xml
    /// </summary>
    /// <param name="doc"></param>
    public void createXml(XmlDocument doc) {
      //加入xml声明段落
      XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
      //加入doc
      doc.AppendChild(xmlDeclaration);
      //创建根元素
      XmlElement install = doc.CreateElement("install");
      //加入根元素
      doc.AppendChild(install);
      //创建安装属性节点
      XmlElement install_properties = doc.CreateElement("install_properties");
      //id
      install_properties.SetAttribute("id", "1");
      //version
      install_properties.SetAttribute("version", "1");
      //publishtime
      DateTime date = DateTime.Now;
      install_properties.SetAttribute("publishTime", date.ToString("yyyy-MM-dd HH:mm:ss"));
      //将install_properties节点放入install节点
      install.AppendChild(install_properties);

      //创建apps节点
      XmlElement apps = doc.CreateElement("apps");
      //将apps节点放入install节点
      install.AppendChild(apps);
    }
    #endregion

    #region 查找是否存在了指定的应用节点
    /// <summary>
    /// 查找是否存在了指定的应用节点
    /// </summary>
    /// <param name="doc"></param>
    /// <param name="appFileName"></param>
    /// <returns></returns>
    private Boolean checkAppNode(XmlDocument doc, String appFileName) {
      XmlNodeList nodelist = doc.SelectNodes("/install/apps/app");
      foreach(XmlNode node in nodelist){
        if( node.Attributes["appFileName"].Equals(appFileName) ) {
          return true;
        }
      }
      return false;
    }
    #endregion


    private void addApp(App app, String appFileName,XmlDocument doc) {
      if(!checkAppNode(doc,appFileName)){

      }
    }
  }
}

